package com.service.business.merchant.controller;

import com.beust.jcommander.internal.Lists;
import com.service.business.base.dto.LoginUserSession;
import com.service.business.base.service.ConfigService;
import com.service.business.framework.log.RequestLog;
import com.service.business.member.enums.MemberEnums;
import com.service.business.member.service.MemberService;
import com.service.business.member.service.MemberStoreService;
import com.service.business.merchant.controller.rep.MerchantOrderPagRep;
import com.service.business.merchant.controller.req.MerchantOrderCreateReq;
import com.service.business.merchant.controller.req.MerchantOrderPageReq;
import com.service.business.merchant.service.MerchantCreditLineService;
import com.service.business.merchant.service.MerchantOrderService;
import com.service.business.support.Language;
import com.service.business.support.MemberMerchantLockUtils;
import com.service.business.support.MemberStoreLockUtils;
import com.service.business.support.SessionUtil;
import com.service.business.utils.I18nUtil;
import com.service.core.exception.CommonException;
import com.service.core.rest.BaseController;
import com.service.core.rest.request.PageRequest;
import com.service.core.rest.response.BaseResponse;
import com.service.core.rest.response.PageResponse;
import com.service.dao.constants.ConfigConstants;
import com.service.dao.enums.CoinsEnum;
import com.service.dao.enums.MerchantOrderEnums;
import com.service.dao.model.*;
import com.service.utility.common.MathUtil;
import org.redisson.RedissonLock;
import org.redisson.RedissonRedLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;


/**
 * 商家订单表
 *
 * @author xxxx
 * @email xxxx@qq.com
 * @date 2020-03-28 12:54:56
 */
@RestController
@RequestMapping("merchant-order")
public class MerchantOrderController extends BaseController {
    @Autowired
    private SessionUtil sessionUtil;
    @Autowired
    private MemberService memberService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private MemberStoreService storeService;
    @Autowired
    private MemberStoreLockUtils storeLockUtils;
    @Autowired
    private MerchantOrderService merchantOrderService;
    @Autowired
    private MerchantCreditLineService creditLineService;

    @PostMapping("page")
    @RequestLog("核销订单分页接口")
    public PageResponse<MerchantOrderPagRep> page(@RequestBody MerchantOrderPageReq pageRequest) {
        return successQueryPageResponse(merchantOrderService.page(pageRequest));
    }

    @PostMapping("add")
    @RequestLog("创建核销订单")
    public BaseResponse addOrder(@RequestBody @Validated MerchantOrderCreateReq createReq) {
        Member member = memberService.getMemberByAccount(createReq.getMemberLoginAccount(), MemberEnums.Status.ACTIVE);
        if (ObjectUtils.isEmpty(member)) {
            throw new CommonException("暂无此会员", "not_found_user");
        }
//        MemberStore store = storeService.getMemberStore(member.getId(), CoinsEnum.MU.getName());
//        try {
//            if (storeLockUtils.lock(member.getId(), store.getId())) {
//                merchantOrderService.add(createReq, member);
//            }
//        } finally {
//            storeLockUtils.unlock(member.getId(), store.getId());
//        }
        return successBaseResponse();
    }

    @PostMapping("write-off/{orderNo}")
    @RequestLog("核销")
    public BaseResponse writeOff(@PathVariable("orderNo") String orderNo) {

        MerchantOrder order = merchantOrderService.getByOrderNo(orderNo);
        if (ObjectUtils.isEmpty(order)) {
            throw new CommonException("不存在此订单", "merchant_order_exception_not_exist");
        }
        if (ObjectUtils.nullSafeEquals(order.getOrderStatus(), MerchantOrderEnums.Status.write_off.getCode())) {
            throw new CommonException("此订单已核销", "merchant_order_exception_write_off");
        }

        LoginUserSession session = sessionUtil.getUser();
        SysConfig creditCofing = configService.getConfigByName(ConfigConstants.MERCHANT_CREDIT_LINE_COINS);
        CoinsEnum coins = CoinsEnum.valueOf(creditCofing.getConfOptions());
        MemberStore exdfStore = storeService.getMemberStore(session.getUserId(), coins.getName());

        MerchantCreditLine creditLine = creditLineService.getCreditLine(order.getMerchantId(), coins);

        BigDecimal useNum = creditLine.getCreditNum().subtract(creditLine.getResidueNum());
        if(!MathUtil.isLEZero(exdfStore.getNum()) && !MathUtil.isLEZero(useNum)){
            String msg = I18nUtil.getMessage("merchant_credit_line_not_repayment", Language.LANG.get(), CoinsEnum.EXDF.getName());
            throw new CommonException(msg);
        }

        BigDecimal totalNum = exdfStore.getNum().add(creditLine.getCreditNum());
        if (totalNum.compareTo(order.getTotalConcessionNum()) < 0) {
            String msg = I18nUtil.getMessage("merchant_order_exception_store_not_enough", Language.LANG.get(), CoinsEnum.EXDF.getName());
            throw new CommonException(msg);
        }

//        List<MemberStore> storeList = Lists.newArrayList(
//                exdfStore,
//                storeService.getMemberStore(session.getUserId(), CoinsEnum.MU.getName()),
//                storeService.getMemberStore(order.getMemberId(), CoinsEnum.MU.getName())
//        );
//        List<String> lockKeyList = MemberStoreLockUtils.buildStoreKey2List(storeList);
//        lockKeyList.add(MemberMerchantLockUtils.buildOrderLock(orderNo));
//        lockKeyList.add(MemberMerchantLockUtils.buildCreditLineLock(order.getMerchantId(), coins.getName()));

//        RedissonRedLock redLock = storeLockUtils.getRedLock(lockKeyList);
//        try {
//            if (storeLockUtils.redLockTryLock(redLock)) {
//                merchantOrderService.writeOff(order, session.getUserId(), exdfStore, creditLine);
//            }
//        } finally {
//            redLock.unlock();
//        }

        return successBaseResponse();
    }

}
